/*
* 矩阵 和 数组 相关的工具
* */
const matrixToolkit = {
  makeRow(v = 0) {
    const array = new Array(9);
    array.fill(v);
    return array
  },

  makeMatrix(v = 0) {
    // const array = new Array(9);
    // array.fill(makeRow(v));
    // return array
    return Array.from({length: 9}, () => this.makeRow(v))
  },

// 生成数独数据结构测试
// const a = makeMatrix();
// a[0][1] = 2;
// console.log(a)

// 随机算法  Fisher-Yates 洗牌算法
  shuffle(array) {
    const endIndex = array.length - 2;
    for (let i = 0; i <= endIndex; i++) {
      const j = i + Math.floor(Math.random() * (array.length - i));
      // es6 解构，进行数据交换
      [array[i], array[j]] = [array[j], array[i]]
    }
    return array
  },
  // 检查指定位置是否可以填写 n
  checkFillAble(matrix, n, rowIndex, colIndex) {
    const row = matrix[rowIndex];
    // const column = [[matrix[0][colIndex]],[matrix[1][colIndex]],[matrix[2][colIndex]] ... ]
    const column = this.makeRow().map((v, i) => matrix[i][colIndex]);
    const {boxIndex} = boxToolkit.convertToBoxIndex(rowIndex, colIndex);
    const box = boxToolkit.getBoxCells(boxIndex, matrix);
    // 判断里面数据是否完整
    for (let i = 0; i < 9; i++) {
      if (row[i] === n || column[i] === n || box[i] === n) {
        return false
      }
    }
    return true;
  }
}
/*
* 宫坐标系的工具
* */
const boxToolkit = {
  convertToBoxIndex(rowIndex, colIndex) {
    return {
      boxIndex: Math.floor(rowIndex / 3) * 3 + Math.floor(colIndex / 3),
      cellIndex: rowIndex % 3 * 3 + colIndex % 3
    }
  },
  convertFromBoxIndex(boxIndex, cellIndex) {
    return {
      rowIndex: Math.floor(boxIndex / 3) * 3 + Math.floor(cellIndex / 3),
      colIndex: boxIndex % 3 * 3 + cellIndex % 3
    }
  },
  // 获取 box 的数据
  getBoxCells(boxIndex, matrix) {
    const startRowIndex = Math.floor(boxIndex / 3) * 3;
    const startColIndex = boxIndex % 3 * 3;
    const result = [];
    for (let cellIndex = 0; cellIndex < 9; cellIndex++) {
      const rowIndex = startRowIndex + Math.floor(cellIndex / 3);
      const colIndex = startColIndex + cellIndex % 3;
      result.push(matrix[rowIndex][colIndex])
    }
    return result
  }
};

module.exports = class Toolkit {
  static get matrix() {
    return matrixToolkit
  }

  static get box() {
    return boxToolkit
  }
};
